package com.df.gameserver.net.websocket.handler;

import com.df.gameserver.modules.user.UserManager;
import com.df.gameserver.net.MsgDispatcher;
import com.df.gameserver.test.SyncPositionTest;
import com.google.protobuf.GeneratedMessageV3;
import com.manager.MsgManager;
import com.msg.Move;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


@Slf4j
public class FrameToMsgHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
        //        System.out.println(msg.content().toString(Charset.defaultCharset()));
        if (msg instanceof BinaryWebSocketFrame) {
            ByteBuf content = msg.content();

            //数据总长(int)+ msgId(int)+数据体
            int dataAllLength = content.readInt();
            if (dataAllLength < 4) {
//                msg.retain();
                return;
            }//4557
            int msgId = content.readInt();
            Class<? extends GeneratedMessageV3> msgClass = MsgManager.getInstance().getMsgClass(msgId);
            if (msgClass == null) {
                log.warn("收到未定义的消息id：" + msgId);
                return;
            }
            byte[] data = new byte[dataAllLength - 4 - 4];
            content.readBytes(data);
            if(msgId ==-1330431105){//测试下protocstuff,测试通过
                Schema<SyncPositionTest> schema =  RuntimeSchema.getSchema(SyncPositionTest.class);
                SyncPositionTest bean = null;
                try {
                    bean = schema.newMessage();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(data != null)
                    ProtobufIOUtil.mergeFrom(data, bean, schema);
                System.out.println("protocstuff测试结果："+bean);
            }
            Method method = MsgManager.getInstance().getMethod(msgClass);
            if (method == null) {
                return;
            }
            try {
                Object msgObj = method.invoke(null, data);
                MsgDispatcher.getInstance().dispatchMsg(ctx.channel(), msgId, msgObj);
            } catch (Exception e) {
                System.out.println("消息解析失败，消息id："+msgId+"待解析数据："+new String(data, StandardCharsets.UTF_8));
                e.printStackTrace();
                return;
            }

//            Scr


        } else if (msg instanceof ContinuationWebSocketFrame) {

        } else if (msg instanceof TextWebSocketFrame) {

        } else {
            log.warn("收到未知类型的消息：" + msg.content().toString(Charset.defaultCharset()));
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        AttributeKey<String> userIdKey = UserManager.getInstance().userIdKey;
        Attribute<String> attr = ctx.attr(userIdKey);
        String userId = attr.get();
        UserManager.getInstance().removeUser(userId);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        AttributeKey<String> userIdKey = UserManager.getInstance().userIdKey;
        Attribute<String> attr = ctx.attr(userIdKey);
        String userId = attr.get();
        UserManager.getInstance().removeUser(userId);
        super.exceptionCaught(ctx, cause);
    }
}
